#ifndef __M_HOST_H__
#define __M_HOST_H__
#include"mq_bingding.hpp"
#include"mq_exchage.hpp"
#include"mq_message.hpp"
#include"mq_queue.hpp"
#include"../mqcommon/mq_proto.pb.h"
#include<google/protobuf/map.h>
namespace bitmq{
class VirtualHost{
    public:
    using ptr=std::shared_ptr<VirtualHost>;
    VirtualHost(std::string basedir, std::string dbfile)
    :_emp(std::make_shared<ExchageManager>(dbfile)),
    _mqmp(std::make_shared<MsgqueueManager>(dbfile)),
    _bmp(std::make_shared<BingdingManager>(dbfile)),
    _mmp(std::make_shared<MessageManager>(basedir))
    {
        MsgQueueMap mqp=_mqmp->getall();
        for(auto&e:mqp)
        {
            _mmp->initQueueMessage(e.first);
        }
    }
    //声明交换机
    bool declareExchange(const std::string& ename,ExchageType type,bool durable,bool auto_delete,const google::protobuf::Map<std::string, std::string>& args)
    {
        return _emp->declareExchage(ename,type,durable,auto_delete,args);
    }
    //删除交换机
    void deleteExchange(const std::string&ename)
    {
        //1、先删除交换机相关的绑定信息
        _bmp->removeExchangeBingdings(ename);
        //2、删除交换机
        _emp->deleteExchage(ename);
    }
    bool existsExchange(const std::string&ename)
    {
        return _emp->exists(ename);
    }
    Exchage::ptr selectExchange(const std::string&ename)
    {
        return _emp->selectExchage(ename);
    }
    //声明队列
    bool declareQueue(const std::string qname,
        bool durable,
        bool exclusive,
        bool auto_delete,
        const google::protobuf::Map<std::string, std::string>& args)
        {
            _mmp->initQueueMessage(qname);
            return _mqmp->declareQueue(qname,durable,exclusive,auto_delete,args);
        }
    //删除队列
    void deleteQueue(const std::string&qname)
    {
        //删除队列要删除队列的相关数据  队列的消息 和队列的绑定数据
        _mmp->destroyQueueMessage(qname);
        _bmp->removeQueueBingdings(qname);
        _mqmp->remove(qname);
    }
    //判断队列是否存在
    bool existsQueue(const std::string&qname)
    {
        return _mqmp->exists(qname);
    }
    //获取所有队列
    MsgQueueMap getQueues()
    {
        return _mqmp->getall();
    }
    //绑定
    bool bind(const std::string&ename,const std::string&qname,const std::string&key)
    {
        Exchage::ptr eptr=_emp->selectExchage(ename);
        if(eptr.get()==nullptr)
        {
            DLOG("绑定失败，没有找到相关交换机%s！",ename.c_str());
            return false;
        }

        MessageQueue::ptr qptr=_mqmp->selectQueue(qname);
        if(qptr.get()==nullptr)
        {
            DLOG("绑定失败，没有找到相关队列%s！",qname.c_str());
            return false;
        }

        return _bmp->bind(ename,qname,key,eptr->_durable&qptr->_durable);
    }
    //解绑
    void unbind(const std::string&ename,const std::string&qname)
    {
        _bmp->unbind(ename,qname);
    }
    QueueBingdingMap getbinds(const std::string&ename)//获取交换机所有绑定关系
    {
        return _bmp->getExchangeBingdings(ename);
    }
    bool existsBindings(const std::string&ename,const std::string&qname)
    {
        return _bmp->exists(ename,qname);
    }
    //发布消息
    bool basicPublic(const std::string&qname,bitmq::BasicProperties*bp,const std::string&body)
    {
        MessageQueue::ptr mqp=_mqmp->selectQueue(qname);
        if(mqp.get()==nullptr)
        {
            DLOG("发布消息失败,队列不存在！");
            return false;
        }

        return _mmp->insert(qname,bp,body,mqp->_durable);
    }
    //消费消息
    MessagePtr basicConsume(const std::string&qname)
    {
        return _mmp->getFrontMessage(qname);
    }
    //确认应答
    bool basicAck(const std::string qname,const std::string&msgid)
    {   
        return _mmp->ack(qname,msgid);
    }

    void clear()
    {
        _emp->clear();
        _mqmp->clear();
        _bmp->clear();
        _mmp->clear();
    }
    private:
    ExchageManager::ptr _emp;
    MsgqueueManager::ptr _mqmp;
    BingdingManager::ptr _bmp;
    MessageManager::ptr _mmp;
};

}
#endif